import React, {useEffect, useRef, useState} from "react";
import FileApi, {FileObj} from "@/api/web/FileApi.ts";
import hljs from 'highlight.js';
import useThemeStore from "@/store/ThemeStore.ts";
import {createStyles} from "antd-style";
import {ViewProcessor} from "@/components/FilePreviewProcess/processors/_index.ts";

const useStyles = createStyles(({css, token}) => {
    return {
        atomOneDark: css`
            pre code.hljs {
                display: block;
                overflow-x: auto;
                padding: 1em
            }

            code.hljs {
                padding: 3px 5px
            }

            .hljs {
                color: #abb2bf;
                background: #282c34
            }

            .hljs-comment, .hljs-quote {
                color: #5c6370;
                font-style: italic
            }

            .hljs-doctag, .hljs-formula, .hljs-keyword {
                color: #c678dd
            }

            .hljs-deletion, .hljs-name, .hljs-section, .hljs-selector-tag, .hljs-subst {
                color: #e06c75
            }

            .hljs-literal {
                color: #56b6c2
            }

            .hljs-addition, .hljs-attribute, .hljs-meta .hljs-string, .hljs-regexp, .hljs-string {
                color: #98c379
            }

            .hljs-attr, .hljs-number, .hljs-selector-attr, .hljs-selector-class, .hljs-selector-pseudo, .hljs-template-variable, .hljs-type, .hljs-variable {
                color: #d19a66
            }

            .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-symbol, .hljs-title {
                color: #61aeee
            }

            .hljs-built_in, .hljs-class .hljs-title, .hljs-title.class_ {
                color: #e6c07b
            }

            .hljs-emphasis {
                font-style: italic
            }

            .hljs-strong {
                font-weight: 700
            }

            .hljs-link {
                text-decoration: underline
            }
        `,
        atomOneLight: css`
            pre code.hljs {
                display: block;
                overflow-x: auto;
                padding: 1em
            }

            code.hljs {
                padding: 3px 5px
            }

            .hljs {
                color: #383a42;
                background: #fafafa
            }

            .hljs-comment, .hljs-quote {
                color: #a0a1a7;
                font-style: italic
            }

            .hljs-doctag, .hljs-formula, .hljs-keyword {
                color: #a626a4
            }

            .hljs-deletion, .hljs-name, .hljs-section, .hljs-selector-tag, .hljs-subst {
                color: #e45649
            }

            .hljs-literal {
                color: #0184bb
            }

            .hljs-addition, .hljs-attribute, .hljs-meta .hljs-string, .hljs-regexp, .hljs-string {
                color: #50a14f
            }

            .hljs-attr, .hljs-number, .hljs-selector-attr, .hljs-selector-class, .hljs-selector-pseudo, .hljs-template-variable, .hljs-type, .hljs-variable {
                color: #986801
            }

            .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-symbol, .hljs-title {
                color: #4078f2
            }

            .hljs-built_in, .hljs-class .hljs-title, .hljs-title.class_ {
                color: #c18401
            }

            .hljs-emphasis {
                font-style: italic
            }

            .hljs-strong {
                font-weight: 700
            }

            .hljs-link {
                text-decoration: underline
            }
        `,
    }
})

const _main = ({fileObj}: { fileObj: FileObj }) => {
    const [text, setText] = useState<string>('')
    const codeRef = useRef<HTMLElement | null>(null);
    const [type, setType] = useState<string | null>(fileObj.type)
    const theme = useThemeStore(state => state.theme)
    const styles = useStyles().styles;

    useEffect(() => {
        // 需要返回销毁请求
        const destroy = FileApi.getFileAsString(fileObj.path, (value) => {
            setText(pre => {
                const s = pre + value;
                if (s.length > 2000) {
                    destroy()
                    return s.substring(0, 2000)
                } else {
                    return s
                }
            })
        })
        return () => {
            destroy()
        }
    }, []);

    useEffect(() => {
        if (codeRef.current == null) return
        if (type != null) {
            const languages = hljs.listLanguages();
            for (let language of languages) {
                if (language == fileObj.type) {
                    const result = hljs.highlight(text, {
                        language,
                    })
                    codeRef.current.innerHTML = result.value
                    return
                }
            }
        }
        const result = hljs.highlightAuto(text)
        setType(result.language ? result.language : "text")
        codeRef.current.innerHTML = result.value
    }, [text, codeRef]);

    return (
        <pre
            className={theme.type == 'dark' ?
                styles.atomOneDark :
                styles.atomOneLight
            }
            style={{
                width: "auto",
                overflow: "auto",
                position: "relative",
            }}
        >
            <h3>文本类型：{type}</h3>
            <code ref={codeRef}>
            </code>
        </pre>
    )
}

export default class TextView extends ViewProcessor {
    uniKey = "TextView"

    isViewAble = () => {
        const mimes = ['application/xml', 'text']
        if (this.fileObj.contentType != null && this.fileObj.contentType != '') {
            for (let m of mimes) {
                if (this.fileObj.contentType.startsWith(m)) {
                    return true
                }
            }
        }
        const types = ['js', 'json', 'yaml']
        if (this.fileObj.type != null && this.fileObj.type != '') {
            for (let t of types) {
                if (this.fileObj.type == t) {
                    return true
                }
            }
        }
        return false
    }

    ViewFunctionComponent = () => <_main fileObj={this.fileObj}/>

    getName = () => "文本（可能不完整）"
}
